package memory.memoryCopy;

/**
 * @Author wsyjiamian@163.com
 * @Description Java中的clone函数
 * @Date 2020/8/16 12:52
 */

public class CloneCopy {

    public static void main(String[] args) {
        Men m = new Men("zs" , 12, new Son("ww" , 10));
        try {
            Men m1 = (Men)m.clone();

            //通过打印发现两者地址不一样了，修改值也互不干涉
            //栈内存        堆内存（对一个Men对象）
            //  m  ------  new Men
            //  |
            //  m1 ------  new Men
            System.out.println("m1 == m " + m1 + " " + m);
            m.name = "ls";
            System.out.println("m1.name == m.name  " + m1.name + " " + m.name);

            //假设在new Men中含有另一个对象，而另一个对象没有实现Cloneable接口，又会发生什么情况呢？
            //打印后，会发现拷贝个 son 的地址是一样的，也就是说在这里的拷贝没有完成对值的拷贝
            //通过对m的son赋值为null，发现和使用等号赋值后引用变量的变化一致，也就是说还是拷贝了一次引用变量

            //栈内存        堆内存(不同的Men对象)           堆内存(同一个Son对象)
            //  m  ------  new Men ----
            //  m.son
            //  |                                        new Son
            //  m1 ------  new Men ----
            //  m1.son

            Men m2 = (Men)m.clone();
            System.out.println("m2.son == m.son " + m2.son + " " + m.son);
            m.son = null;
            System.out.println("m2.son == m.son " + m2.son + " " + m.son);


        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }

    static class Men implements Cloneable{
        String name;
        int age;
        Son son;

        public Men(String name , int age , Son son){
            this.name = name;
            this.age = age;
            this.son = son;
        }

        @Override
        public Object clone() throws CloneNotSupportedException {
             return super.clone();
        }
    }

    static class Son{
        String name;
        int age;
        public Son(String name , int age){
            this.name = name;
            this.age = age;
        }
    }
}
